#include <ceres/ceres.h>

using ceres::CENTRAL;
using ceres::CostFunction;
using ceres::NumericDiffCostFunction;
using ceres::Problem;
using ceres::Solve;
using ceres::Solver;

// Minimize 0.5*(10-x)^2
//  1. using Jacobian matrix
//  2. computed using numeric differentiation
struct CostFunctor
{
    template <typename T>
    bool operator()(const T *const x, T *residual) const
    {
        // its derivative as jacobian
        residual[0] = 10.0 - x[0];
        return true;
    }
};

int main()
{
    // the input variable
    double x = 0.5;
    const double initial_x = x;

    // the cost function known as residual
    CostFunction *cost_function =
        new NumericDiffCostFunction<CostFunctor, CENTRAL, 1, 1>(new CostFunctor);

    Problem problem;

    // use input and cost function to construct a problem
    problem.AddResidualBlock(cost_function, nullptr, &x);

    // options: parameters to control actions of the sovler
    // summary: save the intermediate result for the sovler
    Solver::Options options;
    options.minimizer_progress_to_stdout = true;
    Solver::Summary summary;

    Solve(options, &problem, &summary);

    std::cout << summary.BriefReport() << std::endl;
    std::cout << "x: " << initial_x << " -> " << x << std::endl;

    return 0;
}
